package top.dingyingying.springboot3.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import top.dingyingying.springboot3.aop.AuthInfo;
import top.dingyingying.springboot3.entity.auth.TbUser;
import top.dingyingying.springboot3.service.RedisService;
import top.dingyingying.springboot3.util.IpUtils;

import java.lang.annotation.Annotation;

//@Component 表示该类是一个组件，可以被spring容器管理
@Component
@Slf4j
@RequiredArgsConstructor
public class AppInterceptor implements HandlerInterceptor {
    private final RedisService redisService;
    //    保存登录认证信息的线程线程，可以确保每一个请求的对象保持隔离
    private static final ThreadLocal<AuthInfo> authInfoThreadLocal = new ThreadLocal<>();

    public static AuthInfo getAuthInfo() {
        return authInfoThreadLocal.get();
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        放置认证信息到线程中，发辫其他地方获取
        AuthInfo authInfo = new AuthInfo();
        authInfoThreadLocal.set(authInfo);
//        请求中的认证信息
        String token = request.getHeader("Authorization");
        authInfo.setToken(token);
//        获取token对应的用户id
        if (StringUtils.hasText(token)) {
            authInfo.setUid(redisService.load(token, Integer.class));
        }

//       获取客户端的ip地址信息
        String ip = IpUtils.getIpAddr(request);
//        获取请求路径信息
        String url = request.getRequestURI();
        String method = request.getMethod();
        authInfo.setIp(ip);
        authInfo.setUrl(url);
        authInfo.setMethod(method);

        log.debug("{}访问了{}-{}", ip, url, method);
//        判断是否访问的是控制器
        if (handler instanceof HandlerMethod hm) {
            log.debug("访问了控制器:{}", hm.getBeanType().getSimpleName());
            RequestMapping annotation = hm.getBeanType().getAnnotation(RequestMapping.class);
            String controller = "";
            if (annotation != null && annotation.value().length > 0) {
                controller = annotation.value()[0];
            }
            annotation = hm.getMethodAnnotation(RequestMapping.class);
            if (annotation != null && annotation.value().length > 0) {
                controller += annotation.value()[0];
            }
            log.debug("控制器请求的注解:{}", controller);
            authInfo.setMapping(controller);
            log.debug("认证信息:{}",  authInfo);
        }

        return true;
    }


}
